#ifndef LOG_H
#define LOG_H


#include <mutex>
#include <string>
#include <thread>
#include <sys/time.h>
#include <string.h>
#include <stdarg.h>
#include <assert.h>
#include <sys/stat.h>
#include "blockqueue.h"
#include "../Buffer/buffer.h"


class Log
{
public:
    void init(int level, const char* path = "./log", 
            const char* suffix = ".log",
            int maxQueueCapacity = 1024);

    static Log* Instance();   //单例模式，创建静态的实例
    static void FlushLogThread();

    void write(int level, const char* format, ...);
    void flush();

    int GetLevel();
    void SetLevel(int level);
    bool IsOpen() {return isOpen_;}

private:
    Log();  //私有的构造函数
    void AppendLogLevelTitle_(int level);
    virtual ~Log();
    void AsyncWrite_(); //异步写

private:
    static const int LOG_PATH_LEN = 256;
    static const int LOG_NAME_LEN = 256;
    static const int MAX_LINES = 50000;

    const char* path_;   //路径
    const char* suffix_; //后缀

    int MAX_LINES_;       //一个log文件中能保存的最大行

    int lineCount_;         //行数
    int toDay_;             //日期

    bool isOpen_;

    Buffer buff_;      //使用一个buffer缓冲区
    int level_;
    bool isAsync_;  //是否异步

    FILE* fp_;   //log文件指针
    std::unique_ptr<BlockDeque<std::string>> deque_; //设置阻塞队列
    std::unique_ptr<std::thread> writeThread_;   //写线程的指针
    std::mutex mtx_;                            // 同步日志

};

#define LOG_BASE(level, format, ...) \
    do{\
        Log* log = Log::Instance(); \
        if(log->IsOpen() && log->GetLevel() <= level){\
            log->write(level, format, ##__VA_ARGS__);\
            log->flush();\
        } \
    }while(0);

#define LOG_DEBUG(format, ...) do {LOG_BASE(0, format, ##__VA_ARGS__)}while(0);
#define LOG_INFO(format, ...) do {LOG_BASE(1, format, ##__VA_ARGS__)}while(0);
#define LOG_WARN(format, ...) do {LOG_BASE(2, format, ##__VA_ARGS__)}while(0);
#define LOG_ERROR(format, ...) do {LOG_BASE(3, format, ##__VA_ARGS__)}while(0);

#endif